Boxplot by patient
scc_myb_patients<- subset(scc.big, subset = orig.ident %in% c("SCC2","SCC3","SCC4","SCC5"))
df = FetchData(object = scc_myb_patients,vars = c("orig.ident","MYB","hpv_positive")) %>% group_by(orig.ident,hpv_positive) %>% summarise(
myb = mean(MYB),.groups = "drop_last")
stat.test <- df %>% group_by("hpv_positive") %>%
wilcox_test(myb ~ hpv_positive)
df = reshape2::dcast(df, orig.ident ~ hpv_positive)
Using myb as value column: use value.var to override.
p = ggpaired(df, cond1 = "positive",cond2 = "negative",palette = "jco",
add = "jitter", line.color = "gray", line.size = 0.4,id = "orig.ident", fill = "condition") + theme_minimal()+
# stat_compare_means(method = "wilcox.test",comparisons = list(c("positive","negative")),paired = F)+
stat_summary(fun.data = function(x) data.frame(y=max(x)*1.2, label = paste("Mean=",round(mean(x),digits = 2))), geom="text")+ylab("MYB")+ stat_pvalue_manual(stat.test,y.position = 0.2, label = "Wilcox, p = {p}",remove.bracket = F)
Warning: `gather_()` was deprecated in tidyr 1.2.0.
Please use `gather()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
p

pdf(file = "./Figures/SCC_HPV_MYB_boxplot_bySample.pdf",width = 8)
p
dev.off()
null device
1
HPV DEG boxplots
genes = c("ANLN", "TUBB6", "AXL", "IFT122", "GFM1", "MYB", "JAG1")
myb_vs_hpv = FetchData(object = scc_myb_patients,vars = c("hpv_positive",genes))
df = reshape2::melt(myb_vs_hpv,value.name = "logTPM") %>% dplyr::rename(gene = variable)
Using hpv_positive as id variables
stat.test <- df %>%
group_by(gene) %>%
wilcox_test(logTPM ~ hpv_positive) %>%
mutate(y.position = 5)
stat.test
stat.test <- stat.test %>%
add_xy_position(x = "gene", dodge = 0.8)
p = ggboxplot(
df,
x = "gene",
y = "logTPM",
color = "hpv_positive",
palette = "jco",
add = "jitter"
)+ stat_pvalue_manual(stat.test,y.position = 4, label = "p = {p}",remove.bracket = T)
p

pdf(file = "./Figures/SCC_HPV_genes_all_patients.pdf",width = 8)
p
dev.off()
metagenes_violin_compare.2 = function(dataset,prefix = "",pre_on = c("OSI","NT"),axis.text.x = 11,test = "t.test", programs = c("Hypoxia","TNFa","Cell_cycle"),return_list = F,combine_patients = F){
require(facefuns)
plt.lst = list()
if(combine_patients){
genes_by_tp = FetchData(object = dataset,vars = c("treatment",programs)) %>% filter(treatment %in% pre_on) %>% as.data.frame() #mean expression
formula <- as.formula( paste("c(", paste(programs, collapse = ","), ")~ treatment ") )
#plot and split by patient:
stat.test = compare_means(formula = formula ,data = genes_by_tp,method = test,p.adjust.method = "fdr")%>% # Add pairwise comparisons p-value
dplyr::filter(group1 == pre_on[1] & group2 == pre_on[2]) #filter for pre vs on treatment only
stat.test$p.format =stat.test$p.adj #modift 0 pvalue to be lowest possible float
stat.test$p.format[!stat.test$p.format == 0 ] <- paste("=",stat.test$p.format[!stat.test$p.format == 0 ])
stat.test$p.format[stat.test$p.format == 0 ] <- paste("<",.Machine$double.xmin %>% signif(digits = 3))
genes_by_tp = reshape2::melt(genes_by_tp, id.vars = c("treatment"),value.name = "score")
plt = ggplot(genes_by_tp, aes(x = variable, y = score,fill = treatment)) + geom_split_violin(scale = 'width')+
geom_boxplot(width = 0.25, notch = FALSE, notchwidth = .4, outlier.shape = NA, coef=0)+
ylim(min(genes_by_tp$score),max(genes_by_tp$score)*1.25)
plt = plt +stat_pvalue_manual(stat.test, label = "asd = {p.signif}", label.size = 7, #add p value
y.position = 1,inherit.aes = F,size = 3.3,x = ".y.") # set position at the top value
return(plt)
}
if (return_list) {
return(plt.lst)
}
}
scc_myb_patients$treatment = scc_myb_patients$hpv_positive %>% gsub(pattern = "negative",replacement = "HPV-negative")%>% gsub(pattern = "positive",replacement = "HPV-positive")
scc_myb_patients@meta.data[["treatment"]] = factor(scc_myb_patients$treatment, levels = c("HPV-positive", "HPV-negative"))
p = metagenes_violin_compare.2(dataset = scc_myb_patients, prefix = "patient",pre_on = c("HPV-negative","HPV-positive"),test = "wilcox.test",programs = genes, return_list = F,combine_patients = T) +scale_y_continuous(limits = c(0,1.5)) + labs(fill = "")+ylab("LogTPM")+xlab("Gene")+theme(axis.title=element_text(size=14))+ scale_fill_manual(values=c("#F8766D", "cyan3"))
Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.
p
Warning: Removed 398 rows containing non-finite values (stat_ydensity).
Warning: Removed 398 rows containing non-finite values (stat_boxplot).

pdf(file = "./Figures/SCC_HPV_Top_violin.pdf",width = 10,height = 5)
p
Warning: Removed 392 rows containing non-finite values (stat_ydensity).
Warning: Removed 392 rows containing non-finite values (stat_boxplot).
dev.off()
null device
1
myplots <- list() # new empty list
for (patient_name in c("SCC2", "SCC3", "SCC4", "SCC5")) {
patient_data = subset(x = scc_myb_patients, subset = orig.ident == patient_name)
df = FetchData(object = patient_data,
vars = c("hpv_positive", "MYB_positive")) %>% droplevels()
test = fisher_test(table(df))
p = ggbarstats(
df,
MYB_positive,
hpv_positive,
results.subtitle = FALSE,
subtitle = paste0("Fisher's exact test", ", p-value = ",
test$p)
,title = patient_name)
myplots[[patient_name]] <- p # add each plot into plot list
}
ggarrange(plotlist = myplots,ncol = 4,nrow = 1)

deg <-
FindMarkers(
scc_myb_patients,
ident.1 = "positive",
ident.2 = "negative",
features = features,
densify = T,
assay = "RNA",
logfc.threshold = 0.1,
min.pct = 0.1,
only.pos = F,
mean.fxn = function(x) {
return(log(rowMeans(x) + 1, base = 2)) # change func to calculate logFC in log space data (default to exponent data)
}
)
| | 0 % ~calculating
|+ | 1 % ~14s
|++ | 2 % ~13s
|++ | 3 % ~14s
|+++ | 4 % ~13s
|+++ | 5 % ~13s
|++++ | 6 % ~13s
|++++ | 7 % ~13s
|+++++ | 8 % ~13s
|+++++ | 9 % ~13s
|++++++ | 10% ~13s
|++++++ | 11% ~13s
|+++++++ | 12% ~13s
|+++++++ | 13% ~13s
|++++++++ | 14% ~13s
|++++++++ | 15% ~12s
|+++++++++ | 16% ~12s
|+++++++++ | 18% ~12s
|++++++++++ | 19% ~12s
|++++++++++ | 20% ~12s
|+++++++++++ | 21% ~12s
|+++++++++++ | 22% ~12s
|++++++++++++ | 23% ~12s
|++++++++++++ | 24% ~11s
|+++++++++++++ | 25% ~12s
|+++++++++++++ | 26% ~11s
|++++++++++++++ | 27% ~11s
|++++++++++++++ | 28% ~11s
|+++++++++++++++ | 29% ~11s
|+++++++++++++++ | 30% ~11s
|++++++++++++++++ | 31% ~11s
|++++++++++++++++ | 32% ~10s
|+++++++++++++++++ | 33% ~10s
|++++++++++++++++++ | 34% ~10s
|++++++++++++++++++ | 35% ~10s
|+++++++++++++++++++ | 36% ~10s
|+++++++++++++++++++ | 37% ~10s
|++++++++++++++++++++ | 38% ~09s
|++++++++++++++++++++ | 39% ~09s
|+++++++++++++++++++++ | 40% ~09s
|+++++++++++++++++++++ | 41% ~09s
|++++++++++++++++++++++ | 42% ~09s
|++++++++++++++++++++++ | 43% ~09s
|+++++++++++++++++++++++ | 44% ~08s
|+++++++++++++++++++++++ | 45% ~08s
|++++++++++++++++++++++++ | 46% ~08s
|++++++++++++++++++++++++ | 47% ~08s
|+++++++++++++++++++++++++ | 48% ~08s
|+++++++++++++++++++++++++ | 49% ~08s
|++++++++++++++++++++++++++ | 51% ~08s
|++++++++++++++++++++++++++ | 52% ~07s
|+++++++++++++++++++++++++++ | 53% ~07s
|+++++++++++++++++++++++++++ | 54% ~07s
|++++++++++++++++++++++++++++ | 55% ~07s
|++++++++++++++++++++++++++++ | 56% ~07s
|+++++++++++++++++++++++++++++ | 57% ~07s
|+++++++++++++++++++++++++++++ | 58% ~06s
|++++++++++++++++++++++++++++++ | 59% ~06s
|++++++++++++++++++++++++++++++ | 60% ~06s
|+++++++++++++++++++++++++++++++ | 61% ~06s
|+++++++++++++++++++++++++++++++ | 62% ~06s
|++++++++++++++++++++++++++++++++ | 63% ~06s
|++++++++++++++++++++++++++++++++ | 64% ~06s
|+++++++++++++++++++++++++++++++++ | 65% ~05s
|+++++++++++++++++++++++++++++++++ | 66% ~05s
|++++++++++++++++++++++++++++++++++ | 67% ~05s
|+++++++++++++++++++++++++++++++++++ | 68% ~05s
|+++++++++++++++++++++++++++++++++++ | 69% ~05s
|++++++++++++++++++++++++++++++++++++ | 70% ~05s
|++++++++++++++++++++++++++++++++++++ | 71% ~05s
|+++++++++++++++++++++++++++++++++++++ | 72% ~05s
|+++++++++++++++++++++++++++++++++++++ | 73% ~04s
|++++++++++++++++++++++++++++++++++++++ | 74% ~04s
|++++++++++++++++++++++++++++++++++++++ | 75% ~04s
|+++++++++++++++++++++++++++++++++++++++ | 76% ~04s
|+++++++++++++++++++++++++++++++++++++++ | 77% ~04s
|++++++++++++++++++++++++++++++++++++++++ | 78% ~04s
|++++++++++++++++++++++++++++++++++++++++ | 79% ~03s
|+++++++++++++++++++++++++++++++++++++++++ | 80% ~03s
|+++++++++++++++++++++++++++++++++++++++++ | 81% ~03s
|++++++++++++++++++++++++++++++++++++++++++ | 82% ~03s
|++++++++++++++++++++++++++++++++++++++++++ | 84% ~03s
|+++++++++++++++++++++++++++++++++++++++++++ | 85% ~03s
|+++++++++++++++++++++++++++++++++++++++++++ | 86% ~02s
|++++++++++++++++++++++++++++++++++++++++++++ | 87% ~02s
|++++++++++++++++++++++++++++++++++++++++++++ | 88% ~02s
|+++++++++++++++++++++++++++++++++++++++++++++ | 89% ~02s
|+++++++++++++++++++++++++++++++++++++++++++++ | 90% ~02s
|++++++++++++++++++++++++++++++++++++++++++++++ | 91% ~02s
|++++++++++++++++++++++++++++++++++++++++++++++ | 92% ~01s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 93% ~01s
|+++++++++++++++++++++++++++++++++++++++++++++++ | 94% ~01s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 95% ~01s
|++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~01s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=16s
intersect(
acc_deg %>% filter(.$fdr<0.05) %>% filter(.$avg_log2FC>0) %>% arrange(dplyr::desc(.$avg_log2FC)) %>% head(400) %>% rownames(),
deg %>% filter(.$fdr<0.05) %>% filter(.$avg_log2FC>0) %>% arrange(dplyr::desc(.$avg_log2FC)) %>% head(400) %>% rownames()
) %>% cat(sep = "\n")
LSM5
ETS2
TMPO
PSME2
TMX1
MSH6
PHB
SNRPD1
MCM3
RNF168
MCM5
MT1E
FBLN1
TXN
TUBA1B
MT2A
STMN1
# HNSC OS p=0.022
intersect(
acc_deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$avg_log2FC))%>% filter(.$avg_log2FC>0) %>% head(200) %>% rownames(),
deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$avg_log2FC))%>% filter(.$avg_log2FC>0) %>% head(200) %>% rownames()
) %>% cat(sep = "\n")
TMPO
PSME2
TMX1
SNRPD1
MCM3
MT1E
MT2A
STMN1
intersect(
acc_deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$fdr))%>% filter(.$avg_log2FC>0) %>% head(200) %>% rownames(),
deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$fdr))%>% filter(.$avg_log2FC>0) %>% head(200) %>% rownames()
) %>% cat(sep = "\n")
LGALS1
GAPDH
TUBA1C
CAPG
TAGLN2
intersect(
acc_deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$fdr))%>% filter(.$avg_log2FC>0) %>% head(400) %>% rownames(),
deg %>% filter(.$fdr<0.05) %>% arrange(dplyr::desc(.$fdr))%>% filter(.$avg_log2FC>0) %>% head(400) %>% rownames()
) %>% cat(sep = "\n")
LGALS1
GAPDH
NDUFS7
MTHFD2
FDFT1
ETS2
KLF10
TUBA1C
CAPG
TAGLN2
# CECS RFS p=0.014
deg %>% filter(.$fdr<0.05) %>% filter(.$avg_log2FC>0) %>% arrange(dplyr::desc(.$avg_log2FC)) %>% rownames() %>% head(20) %>% cat(sep = "\n")
KRT5
IGFBP2
AQP3
HES1
ATP1B3
MT1X
NASP
DEK
SCPEP1
ACTL6A
FABP5
KRT15
GOLIM4
STMN1
ID1
DSC3
PRKDC
LMO4
SELENOP
NUCKS1
acc_deg[deg %>% filter(.$fdr<0.05) %>% filter(.$avg_log2FC>0) %>% arrange(dplyr::desc(.$avg_log2FC)) %>% rownames() %>% head(20),]
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCgoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmBgYAoKYGBge3J9CmBgYAoKIyBEYXRhCgoKYGBge3J9CiMgcmVhZCBwcm9jZXNzZWQgZGF0YToKU0NDMV9jYW5jZXIgID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9jZXJ2aWNhbF9jYW5jZXJfZGF0YS9RaXUgZXQgYWwvU0NDMS9TQ0MxX2NhbmNlci5SRFMiKQpTQ0MyX2NhbmNlciAgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2NlcnZpY2FsX2NhbmNlcl9kYXRhL1FpdSBldCBhbC9TQ0MyL1NDQzJfY2FuY2VyX3Byb2Nlc3NlZC5SRFMiKQpTQ0MzX2NhbmNlciA9IHJlYWRSRFMoZmlsZSA9ICIuL0RhdGEvY2VydmljYWxfY2FuY2VyX2RhdGEvUWl1IGV0IGFsL1NDQzMvU0NDM19jYW5jZXJfcHJvY2Vzc2VkLlJEUyIpClNDQzRfY2FuY2VyID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9jZXJ2aWNhbF9jYW5jZXJfZGF0YS9RaXUgZXQgYWwvU0NDNC9TQ0M0X2NhbmNlcl9wcm9jZXNzZWQuUkRTIikKU0NDNV9jYW5jZXIgID0gcmVhZFJEUyhmaWxlID0gIi4vRGF0YS9jZXJ2aWNhbF9jYW5jZXJfZGF0YS9RaXUgZXQgYWwvU0NDNS9TQ0M1X2NhbmNlcl9wcm9jZXNzZWQuUkRTIikKCnNjYy5iaWcgPC0gbWVyZ2UoU0NDMV9jYW5jZXIsIHkgPSBjKFNDQzJfY2FuY2VyLFNDQzNfY2FuY2VyLCBTQ0M0X2NhbmNlcixTQ0M1X2NhbmNlciksIGFkZC5jZWxsLmlkcyA9IGMoIlNDQzEiLCJTQ0MyIiwgIlNDQzMiLCAiU0NDNCIsIlNDQzUiKSwgcHJvamVjdCA9ICJTQ0MiKQpzY2MuYmlnJG9yaWcuaWRlbnQgPSAgc2FwcGx5KFggPSBzdHJzcGxpdChjb2xuYW1lcyhzY2MuYmlnKSwgc3BsaXQgPSAiXyIpLCBGVU4gPSAiWyIsIDEpCgoKVmxuUGxvdChvYmplY3QgPSBzY2MuYmlnLGZlYXR1cmVzID0gIk1ZQiIsZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsc2xvdCA9ICJkYXRhIiwgYXNzYXkgPSAiUk5BIikKCgpgYGAKCgpgYGB7cn0KbXliX2RhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gc2NjLmJpZyx2YXJzID0gYygiTVlCIiwib3JpZy5pZGVudCIpLHNsb3QgPSAiZGF0YSIsIGFzc2F5ID0gIlJOQSIpCm15Yl9kYXRhICU+JSAgIGdyb3VwX2J5KG9yaWcuaWRlbnQpICU+JSAKICBzdW1tYXJpc2UoY291bnRzID0gc3VtKE1ZQiA+IDAsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMgUHBhdGllbnRzIGZpbHRlcgpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0Kc2NjX215Yl9wYXRpZW50czwtIHN1YnNldChzY2MuYmlnLCBzdWJzZXQgPSBvcmlnLmlkZW50ICVpbiUgYygiU0NDMyIsIlNDQzQiLCJTQ0M1IikpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KHJzdGF0aXgpCm15Yl92c19ocHYgPSBGZXRjaERhdGEob2JqZWN0ID0gc2NjX215Yl9wYXRpZW50cywgdmFycyA9IGMoImhwdl9wb3NpdGl2ZSIsICJNWUIiKSkKZGYgPSByZXNoYXBlMjo6bWVsdChteWJfdnNfaHB2LHZhbHVlLm5hbWUgPSAibG9nVFBNIikgJT4lIGRwbHlyOjpyZW5hbWUoZ2VuZSA9IHZhcmlhYmxlKQoKc3RhdC50ZXN0IDwtIGRmICU+JQogIHdpbGNveF90ZXN0KGxvZ1RQTSB+IGhwdl9wb3NpdGl2ZSkKCnN0YXQudGVzdAoKCgpwID0gZ2dwbG90KG15Yl92c19ocHYsYWVzKCB4ID0gaHB2X3Bvc2l0aXZlLCB5ID0gTVlCKSkgK2dlb21fYm94cGxvdCh3aWR0aD0uMSxvdXRsaWVyLnNoYXBlID0gTkEpICsKICB0aGVtZV9taW5pbWFsKCkrCiAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgZGF0YS5mcmFtZSh5PTAuMzUsIGxhYmVsID0gcGFzdGUoIk1lYW49Iixyb3VuZChtZWFuKHgpLGRpZ2l0cyA9IDIpKSksIGdlb209InRleHQiKSAreWxhYigiYXZlcmFnZSBNWUIiKStnZ3RpdGxlKCJDRUNTIikgKyB4bGFiKCJIUFYgc3RhdHVzIikrCiAgc3RhdF9wdmFsdWVfbWFudWFsKHN0YXQudGVzdCx5LnBvc2l0aW9uID0gMC40MywgbGFiZWwgPSAiV2lsY294LCBwID0ge3B9IixyZW1vdmUuYnJhY2tldCA9IEYsYnJhY2tldC5zaG9ydGVuID0gMC4xLHRpcC5sZW5ndGggPSAwLjAxKStjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMCwwLjUpKQogIAoKCnAKYGBgCmBgYHtyfQpwZGYoZmlsZSA9ICIuL0ZpZ3VyZXMvU0NDX01ZQl9IUFZfYm94cGxvdF9hbGxfcGF0aWVudHMucGRmIixoZWlnaHQgPSA0KQpwCmRldi5vZmYoKQpgYGAKCgoKIyBCb3hwbG90IGJ5IHBhdGllbnQKYGBge3J9CnNjY19teWJfcGF0aWVudHM8LSBzdWJzZXQoc2NjLmJpZywgc3Vic2V0ID0gb3JpZy5pZGVudCAlaW4lIGMoIlNDQzIiLCJTQ0MzIiwiU0NDNCIsIlNDQzUiKSkKCmRmID0gRmV0Y2hEYXRhKG9iamVjdCA9IHNjY19teWJfcGF0aWVudHMsdmFycyA9IGMoIm9yaWcuaWRlbnQiLCJNWUIiLCJocHZfcG9zaXRpdmUiKSkgJT4lIGdyb3VwX2J5KG9yaWcuaWRlbnQsaHB2X3Bvc2l0aXZlKSAlPiUgc3VtbWFyaXNlKAogIG15YiA9IG1lYW4oTVlCKSwuZ3JvdXBzID0gImRyb3BfbGFzdCIpCnN0YXQudGVzdCA8LSBkZiAlPiUgZ3JvdXBfYnkoImhwdl9wb3NpdGl2ZSIpICU+JSAKICB3aWxjb3hfdGVzdChteWIgfiBocHZfcG9zaXRpdmUpCgoKZGYgPSByZXNoYXBlMjo6ZGNhc3QoZGYsIG9yaWcuaWRlbnQgfiBocHZfcG9zaXRpdmUpCgoKcCA9IGdncGFpcmVkKGRmLCBjb25kMSAgPSAicG9zaXRpdmUiLGNvbmQyICAgPSAibmVnYXRpdmUiLHBhbGV0dGUgPSAiamNvIiwKICAgICAgICAgICAgYWRkID0gImppdHRlciIsIGxpbmUuY29sb3IgPSAiZ3JheSIsIGxpbmUuc2l6ZSA9IDAuNCxpZCA9ICJvcmlnLmlkZW50IiwgZmlsbCA9ICJjb25kaXRpb24iKSArIHRoZW1lX21pbmltYWwoKSsKICAjIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGNvbXBhcmlzb25zID0gbGlzdChjKCJwb3NpdGl2ZSIsIm5lZ2F0aXZlIikpLHBhaXJlZCA9IEYpKwogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGZ1bmN0aW9uKHgpIGRhdGEuZnJhbWUoeT1tYXgoeCkqMS4yLCBsYWJlbCA9IHBhc3RlKCJNZWFuPSIscm91bmQobWVhbih4KSxkaWdpdHMgPSAyKSkpLCBnZW9tPSJ0ZXh0IikreWxhYigiTVlCIikrIHN0YXRfcHZhbHVlX21hbnVhbChzdGF0LnRlc3QseS5wb3NpdGlvbiA9IDAuMiwgbGFiZWwgPSAiV2lsY294LCBwID0ge3B9IixyZW1vdmUuYnJhY2tldCA9IEYpCnAKYGBgCmBgYHtyfQpwZGYoZmlsZSA9ICIuL0ZpZ3VyZXMvU0NDX0hQVl9NWUJfYm94cGxvdF9ieVNhbXBsZS5wZGYiLHdpZHRoID0gOCkKcApkZXYub2ZmKCkKYGBgCiMgSFBWIERFRyBib3hwbG90cwoKYGBge3IgZmlnLndpZHRoPTh9CmdlbmVzID0gYygiQU5MTiIsICJUVUJCNiIsICJBWEwiLCAiSUZUMTIyIiwgIkdGTTEiLCAiTVlCIiwgIkpBRzEiKQpteWJfdnNfaHB2ID0gRmV0Y2hEYXRhKG9iamVjdCA9IHNjY19teWJfcGF0aWVudHMsdmFycyA9IGMoImhwdl9wb3NpdGl2ZSIsZ2VuZXMpKQpkZiA9IHJlc2hhcGUyOjptZWx0KG15Yl92c19ocHYsdmFsdWUubmFtZSA9ICJsb2dUUE0iKSAlPiUgZHBseXI6OnJlbmFtZShnZW5lID0gdmFyaWFibGUpCgoKc3RhdC50ZXN0IDwtIGRmICU+JQogICAgZ3JvdXBfYnkoZ2VuZSkgJT4lCiAgd2lsY294X3Rlc3QobG9nVFBNIH4gaHB2X3Bvc2l0aXZlKSAlPiUKICBtdXRhdGUoeS5wb3NpdGlvbiA9IDUpCgpzdGF0LnRlc3QKCnN0YXQudGVzdCA8LSBzdGF0LnRlc3QgJT4lIAogIGFkZF94eV9wb3NpdGlvbih4ID0gImdlbmUiLCBkb2RnZSA9IDAuOCkKCnAgPSBnZ2JveHBsb3QoCiAgZGYsCiAgeCA9ICJnZW5lIiwKICB5ID0gImxvZ1RQTSIsCiAgY29sb3IgPSAiaHB2X3Bvc2l0aXZlIiwKICBwYWxldHRlID0gImpjbyIsCiAgYWRkID0gImppdHRlciIKKSsgc3RhdF9wdmFsdWVfbWFudWFsKHN0YXQudGVzdCx5LnBvc2l0aW9uID0gNCwgbGFiZWwgPSAicCA9IHtwfSIscmVtb3ZlLmJyYWNrZXQgPSBUKQoKcApgYGAKYGBge3J9CnBkZihmaWxlID0gIi4vRmlndXJlcy9TQ0NfSFBWX2dlbmVzX2FsbF9wYXRpZW50cy5wZGYiLHdpZHRoID0gOCkKcApkZXYub2ZmKCkKYGBgCgpgYGB7cn0KbWV0YWdlbmVzX3Zpb2xpbl9jb21wYXJlLjIgPSBmdW5jdGlvbihkYXRhc2V0LHByZWZpeCA9ICIiLHByZV9vbiA9IGMoIk9TSSIsIk5UIiksYXhpcy50ZXh0LnggPSAxMSx0ZXN0ID0gInQudGVzdCIsIHByb2dyYW1zID0gYygiSHlwb3hpYSIsIlRORmEiLCJDZWxsX2N5Y2xlIikscmV0dXJuX2xpc3QgPSBGLGNvbWJpbmVfcGF0aWVudHMgPSBGKXsKICByZXF1aXJlKGZhY2VmdW5zKQogIHBsdC5sc3QgPSBsaXN0KCkKICBpZihjb21iaW5lX3BhdGllbnRzKXsKICAgIGdlbmVzX2J5X3RwID0gRmV0Y2hEYXRhKG9iamVjdCA9IGRhdGFzZXQsdmFycyA9ICBjKCJ0cmVhdG1lbnQiLHByb2dyYW1zKSkgJT4lIGZpbHRlcih0cmVhdG1lbnQgJWluJSBwcmVfb24pICAlPiUgYXMuZGF0YS5mcmFtZSgpICNtZWFuIGV4cHJlc3Npb24KICAgIGZvcm11bGEgPC0gYXMuZm9ybXVsYSggcGFzdGUoImMoIiwgcGFzdGUocHJvZ3JhbXMsIGNvbGxhcHNlID0gIiwiKSwgIil+IHRyZWF0bWVudCAiKSApCiAgICAKICAgICNwbG90IGFuZCBzcGxpdCBieSBwYXRpZW50OiAgIAogICAgc3RhdC50ZXN0ID0gY29tcGFyZV9tZWFucyhmb3JtdWxhID0gZm9ybXVsYSAsZGF0YSA9IGdlbmVzX2J5X3RwLG1ldGhvZCA9IHRlc3QscC5hZGp1c3QubWV0aG9kID0gImZkciIpJT4lICMgQWRkIHBhaXJ3aXNlIGNvbXBhcmlzb25zIHAtdmFsdWUKICAgICAgZHBseXI6OmZpbHRlcihncm91cDEgPT0gcHJlX29uWzFdICYgZ3JvdXAyID09IHByZV9vblsyXSkgICNmaWx0ZXIgZm9yIHByZSB2cyBvbiB0cmVhdG1lbnQgb25seQogICAgCiAgICBzdGF0LnRlc3QkcC5mb3JtYXQgPXN0YXQudGVzdCRwLmFkaiAjbW9kaWZ0IDAgcHZhbHVlIHRvIGJlIGxvd2VzdCBwb3NzaWJsZSBmbG9hdAogICAgc3RhdC50ZXN0JHAuZm9ybWF0WyFzdGF0LnRlc3QkcC5mb3JtYXQgPT0gMCBdIDwtIHBhc3RlKCI9IixzdGF0LnRlc3QkcC5mb3JtYXRbIXN0YXQudGVzdCRwLmZvcm1hdCA9PSAwIF0pCiAgICBzdGF0LnRlc3QkcC5mb3JtYXRbc3RhdC50ZXN0JHAuZm9ybWF0ID09IDAgXSA8LSBwYXN0ZSgiPCIsLk1hY2hpbmUkZG91YmxlLnhtaW4gJT4lIHNpZ25pZihkaWdpdHMgPSAzKSkKICAgIAogICAgCiAgICBnZW5lc19ieV90cCA9IHJlc2hhcGUyOjptZWx0KGdlbmVzX2J5X3RwLCBpZC52YXJzID0gYygidHJlYXRtZW50IiksdmFsdWUubmFtZSA9ICJzY29yZSIpCiAgICBwbHQgPSBnZ3Bsb3QoZ2VuZXNfYnlfdHAsIGFlcyh4ID0gdmFyaWFibGUsIHkgPSBzY29yZSxmaWxsID0gdHJlYXRtZW50KSkgKyBnZW9tX3NwbGl0X3Zpb2xpbihzY2FsZSA9ICd3aWR0aCcpKyAKICAgICAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4yNSwgbm90Y2ggPSBGQUxTRSwgbm90Y2h3aWR0aCA9IC40LCBvdXRsaWVyLnNoYXBlID0gTkEsIGNvZWY9MCkrCiAgICAgIHlsaW0obWluKGdlbmVzX2J5X3RwJHNjb3JlKSxtYXgoZ2VuZXNfYnlfdHAkc2NvcmUpKjEuMjUpCiAgICBwbHQgPSBwbHQgK3N0YXRfcHZhbHVlX21hbnVhbChzdGF0LnRlc3QsIGxhYmVsID0gImFzZCA9IHtwLnNpZ25pZn0iLCBsYWJlbC5zaXplID0gNywgICNhZGQgcCB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS5wb3NpdGlvbiA9IDEsaW5oZXJpdC5hZXMgPSBGLHNpemUgPSAzLjMseCA9ICIueS4iKSAjIHNldCBwb3NpdGlvbiBhdCB0aGUgdG9wIHZhbHVlCiAgICByZXR1cm4ocGx0KQogIH0KICAKICAKICAKICAKICAKICBpZiAocmV0dXJuX2xpc3QpIHsKICAgIHJldHVybihwbHQubHN0KQogIH0KfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEwfQpzY2NfbXliX3BhdGllbnRzJHRyZWF0bWVudCA9IHNjY19teWJfcGF0aWVudHMkaHB2X3Bvc2l0aXZlICU+JSBnc3ViKHBhdHRlcm4gPSAibmVnYXRpdmUiLHJlcGxhY2VtZW50ID0gIkhQVi1uZWdhdGl2ZSIpJT4lIGdzdWIocGF0dGVybiA9ICJwb3NpdGl2ZSIscmVwbGFjZW1lbnQgPSAiSFBWLXBvc2l0aXZlIikKc2NjX215Yl9wYXRpZW50c0BtZXRhLmRhdGFbWyJ0cmVhdG1lbnQiXV0gPSBmYWN0b3Ioc2NjX215Yl9wYXRpZW50cyR0cmVhdG1lbnQsIGxldmVscyA9IGMoIkhQVi1wb3NpdGl2ZSIsICJIUFYtbmVnYXRpdmUiKSkKCnAgPSBtZXRhZ2VuZXNfdmlvbGluX2NvbXBhcmUuMihkYXRhc2V0ID0gc2NjX215Yl9wYXRpZW50cywgcHJlZml4ID0gInBhdGllbnQiLHByZV9vbiA9IGMoIkhQVi1uZWdhdGl2ZSIsIkhQVi1wb3NpdGl2ZSIpLHRlc3QgPSAid2lsY294LnRlc3QiLHByb2dyYW1zID0gZ2VuZXMsIHJldHVybl9saXN0ID0gRixjb21iaW5lX3BhdGllbnRzID0gVCkgK3NjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMS41KSkgKyBsYWJzKGZpbGwgPSAiIikreWxhYigiTG9nVFBNIikreGxhYigiR2VuZSIpK3RoZW1lKGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpKSsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNGODc2NkQiLCAiY3lhbjMiKSkKcApgYGAKCgpgYGB7cn0KcGRmKGZpbGUgPSAiLi9GaWd1cmVzL1NDQ19IUFZfVG9wX3Zpb2xpbi5wZGYiLHdpZHRoID0gMTAsaGVpZ2h0ID0gNSkKcApkZXYub2ZmKCkKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD0xM30KbXlwbG90cyA8LSBsaXN0KCkgICMgbmV3IGVtcHR5IGxpc3QKCmZvciAocGF0aWVudF9uYW1lIGluIGMoIlNDQzIiLCAiU0NDMyIsICJTQ0M0IiwgIlNDQzUiKSkgewogIHBhdGllbnRfZGF0YSA9IHN1YnNldCh4ID0gc2NjX215Yl9wYXRpZW50cywgc3Vic2V0ID0gb3JpZy5pZGVudCA9PSBwYXRpZW50X25hbWUpCiAgZGYgID0gRmV0Y2hEYXRhKG9iamVjdCA9IHBhdGllbnRfZGF0YSwKICAgICAgICAgICAgICAgICAgdmFycyA9IGMoImhwdl9wb3NpdGl2ZSIsICJNWUJfcG9zaXRpdmUiKSkgJT4lIGRyb3BsZXZlbHMoKQogIHRlc3QgPSBmaXNoZXJfdGVzdCh0YWJsZShkZikpCiAgcCA9IGdnYmFyc3RhdHMoCiAgICBkZiwKICAgIE1ZQl9wb3NpdGl2ZSwKICAgIGhwdl9wb3NpdGl2ZSwKICAgIHJlc3VsdHMuc3VidGl0bGUgPSBGQUxTRSwKICAgIHN1YnRpdGxlID0gcGFzdGUwKCJGaXNoZXIncyBleGFjdCB0ZXN0IiwgIiwgcC12YWx1ZSA9ICIsCiAgICAgICAgICAgICAgICAgICAgICB0ZXN0JHApCiAgLHRpdGxlID0gcGF0aWVudF9uYW1lKQogIG15cGxvdHNbW3BhdGllbnRfbmFtZV1dIDwtIHAgICMgYWRkIGVhY2ggcGxvdCBpbnRvIHBsb3QgbGlzdAoKfQpnZ2FycmFuZ2UocGxvdGxpc3QgPSBteXBsb3RzLG5jb2wgPSA0LG5yb3cgPSAxKQoKYGBgCgoKYGBge3J9CnNjY19teWJfcGF0aWVudHMgPSBTZXRJZGVudChzY2NfbXliX3BhdGllbnRzLHZhbHVlID0gImhwdl9wb3NpdGl2ZSIpCnNjY19teWJfcGF0aWVudHMgPSBGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBzY2NfbXliX3BhdGllbnRzLG5mZWF0dXJlcyA9IDEwMDAwKQpmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoc2NjX215Yl9wYXRpZW50cykKCmRlZyA8LQogIEZpbmRNYXJrZXJzKAogICAgc2NjX215Yl9wYXRpZW50cywKICAgIGlkZW50LjEgPSAicG9zaXRpdmUiLAogICAgaWRlbnQuMiA9ICJuZWdhdGl2ZSIsCiAgICBmZWF0dXJlcyA9IGZlYXR1cmVzLAogICAgZGVuc2lmeSA9IFQsCiAgICBhc3NheSA9ICJSTkEiLAogICAgbG9nZmMudGhyZXNob2xkID0gMC4xLAogICAgbWluLnBjdCA9IDAuMSwKICAgIG9ubHkucG9zID0gRiwKICAgIG1lYW4uZnhuID0gZnVuY3Rpb24oeCkgewogICAgICByZXR1cm4obG9nKHJvd01lYW5zKHgpICsgMSwgYmFzZSA9IDIpKSAjIGNoYW5nZSBmdW5jIHRvIGNhbGN1bGF0ZSBsb2dGQyBpbiBsb2cgc3BhY2UgZGF0YSAoZGVmYXVsdCB0byBleHBvbmVudCBkYXRhKQogICAgfQogICkKZGVnJGZkcjwtcC5hZGp1c3QocCA9IGFzLnZlY3RvcihkZWckcF92YWwpICxtZXRob2QgPSAiZmRyIiApCgoKCmBgYAoKCgpgYGB7cn0KaW50ZXJzZWN0KAogIGFjY19kZWcgJT4lIGZpbHRlciguJGZkcjwwLjA1KSAlPiUgZmlsdGVyKC4kYXZnX2xvZzJGQz4wKSAgICU+JSBhcnJhbmdlKGRwbHlyOjpkZXNjKC4kYXZnX2xvZzJGQykpICAlPiUgaGVhZCg0MDApICU+JSByb3duYW1lcygpLAogIGRlZyAlPiUgZmlsdGVyKC4kZmRyPDAuMDUpICU+JSBmaWx0ZXIoLiRhdmdfbG9nMkZDPjApICU+JSBhcnJhbmdlKGRwbHlyOjpkZXNjKC4kYXZnX2xvZzJGQykpICU+JSBoZWFkKDQwMCkgJT4lIHJvd25hbWVzKCkKKSAlPiUgY2F0KHNlcCA9ICJcbiIpCmBgYApgYGB7cn0KIyBITlNDIE9TIHA9MC4wMjIKaW50ZXJzZWN0KAogICBhY2NfZGVnICU+JSBmaWx0ZXIoLiRmZHI8MC4wNSkgJT4lIGFycmFuZ2UoZHBseXI6OmRlc2MoLiRhdmdfbG9nMkZDKSklPiUgZmlsdGVyKC4kYXZnX2xvZzJGQz4wKSAlPiUgaGVhZCgyMDApICU+JSByb3duYW1lcygpLAogICBkZWcgJT4lIGZpbHRlciguJGZkcjwwLjA1KSAlPiUgYXJyYW5nZShkcGx5cjo6ZGVzYyguJGF2Z19sb2cyRkMpKSU+JSBmaWx0ZXIoLiRhdmdfbG9nMkZDPjApICU+JSBoZWFkKDIwMCkgJT4lIHJvd25hbWVzKCkKICkgJT4lIGNhdChzZXAgPSAiXG4iKQpgYGAKYGBge3J9CmludGVyc2VjdCggIyBPUyBITlNDIDAuMDMyIENFQ1MgMC4wNjUKICAgYWNjX2RlZyAlPiUgZmlsdGVyKC4kZmRyPDAuMDUpICU+JSBhcnJhbmdlKGRwbHlyOjpkZXNjKC4kZmRyKSklPiUgZmlsdGVyKC4kYXZnX2xvZzJGQz4wKSAlPiUgaGVhZCgyMDApICU+JSByb3duYW1lcygpLAogICBkZWcgJT4lIGZpbHRlciguJGZkcjwwLjA1KSAlPiUgYXJyYW5nZShkcGx5cjo6ZGVzYyguJGZkcikpJT4lIGZpbHRlciguJGF2Z19sb2cyRkM+MCkgJT4lIGhlYWQoMjAwKSAlPiUgcm93bmFtZXMoKQogKSAlPiUgY2F0KHNlcCA9ICJcbiIpCmBgYApgYGB7cn0KaW50ZXJzZWN0KCAKICAgYWNjX2RlZyAlPiUgZmlsdGVyKC4kZmRyPDAuMDUpICU+JSBhcnJhbmdlKGRwbHlyOjpkZXNjKC4kZmRyKSklPiUgZmlsdGVyKC4kYXZnX2xvZzJGQz4wKSAlPiUgaGVhZCg0MDApICU+JSByb3duYW1lcygpLAogICBkZWcgJT4lIGZpbHRlciguJGZkcjwwLjA1KSAlPiUgYXJyYW5nZShkcGx5cjo6ZGVzYyguJGZkcikpJT4lIGZpbHRlciguJGF2Z19sb2cyRkM+MCkgJT4lIGhlYWQoNDAwKSAlPiUgcm93bmFtZXMoKQogKSAlPiUgY2F0KHNlcCA9ICJcbiIpCmBgYAoKYGBge3J9CiMgQ0VDUyBSRlMgcD0wLjAxNApkZWcgJT4lIGZpbHRlciguJGZkcjwwLjA1KSAlPiUgZmlsdGVyKC4kYXZnX2xvZzJGQz4wKSAlPiUgYXJyYW5nZShkcGx5cjo6ZGVzYyguJGF2Z19sb2cyRkMpKSAlPiUgcm93bmFtZXMoKSAlPiUgaGVhZCgyMCkgJT4lIGNhdChzZXAgPSAiXG4iKQpgYGAKCmBgYHtyfQphY2NfZGVnW2RlZyAlPiUgZmlsdGVyKC4kZmRyPDAuMDUpICU+JSBmaWx0ZXIoLiRhdmdfbG9nMkZDPjApICU+JSBhcnJhbmdlKGRwbHlyOjpkZXNjKC4kYXZnX2xvZzJGQykpICU+JSByb3duYW1lcygpICU+JSBoZWFkKDIwKSxdCmBgYAoK